package com.obs.demo.service.impl;


import com.obs.demo.common.result.Result;
import com.obs.demo.common.utils.DateUtils;
import com.obs.demo.controller.vo.ObsVo;
import com.obs.demo.service.ObsService;
import com.obs.services.ObsClient;
import com.obs.services.model.PostSignatureRequest;
import com.obs.services.model.PostSignatureResponse;
import com.obs.services.model.PutObjectResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class ObsServiceImpl implements ObsService {

    @Value("${obs.file}")
    private String uploadUrl;
    @Value("${obs.endpoint}")
    private String endpoint;
    @Value("${obs.access.key}")
    private String accessKey;
    @Value("${obs.secret.key}")
    private String secretKey;
    @Value("${obs.bucket.name}")
    private String bucketName;

    @Override
    public Result<ObsVo> upLoadOne(MultipartFile file, String model, HttpServletRequest request) {
        if (StringUtils.isEmpty(model) || file.isEmpty()) {
            return new Result(200, "OK");
        }
        String originName = file.getOriginalFilename();
        String fileName = this.getRandomName(this.nullHandler(originName));// 生成文件名称
        String dateStr = DateUtils.getFormatDate(DateUtils.DateFmtPattern.YYYYMMDDHH, new Date());
        ObsVo attach = new ObsVo();
        // 服务器访问地址
        String realUrl = new StringBuilder(uploadUrl).append(model).append("/").append(dateStr).append("/").toString();
        try {
            PutObjectResult result = this.uploadObsService(realUrl, fileName, file);
            attach.setFileName(originName);
            attach.setFileUrl(result.getObjectKey());
        } catch (Exception e) {
            throw new RuntimeException("上传Obs异常", e);
        }
        return new Result(200, "OK", attach);
    }


    public PostSignatureResponse getObsFormInfo() {
        // 设置表单参数
        Map<String, Object> formParams = new HashMap<String, Object>();
        // 设置对象访问权限为公共读
        formParams.put("x-obs-acl", "public-read");
        // 设置对象MIME类型
        formParams.put("content-type", "text/plain");
        // 设置成功后的跳转地址，如果前端是通过 XHR/fetch 请求，不要设置此参数，默认表单请求才需要跳转
        // formParams.put("success_action_redirect", "http://localhost:3000/obs-form-upload/success.html");
        PostSignatureRequest request = new PostSignatureRequest();
        request.setFormParams(formParams);
        // 设置表单上传请求有效期，单位：秒
        request.setExpires(3600);
        // 创建ObsClient实例
        ObsClient obsClient = null;
        PostSignatureResponse postSignature = null;
        try {
            obsClient = new ObsClient(accessKey, secretKey, endpoint);
            postSignature = obsClient.createPostSignature(request);
        } catch (Exception e) {
            throw new RuntimeException("获取Obs信息异常", e);
        } finally {
            try {
                if (obsClient != null) {
                    obsClient.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("关闭OBS异常", e);
            }
        }
        return postSignature;
    }

    public PutObjectResult uploadObsService(String fileUrl, String fileName, MultipartFile file) {
        if (file == null) {
            return null;
        }
        ObsClient obsClient = new ObsClient(accessKey, secretKey, endpoint);
        PutObjectResult result = null;
        try {
            result = obsClient.putObject(bucketName, fileUrl + fileName, file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                obsClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 关闭obsClient
        return result;
    }

    /**
     * 获取文件名
     *
     * @param fileName
     * @return
     */
    public String getRandomName(String fileName) {
        int index = fileName.lastIndexOf(".");
        String lastName = fileName.substring(index);//获取后缀名
        String uuidFileName = UUID.randomUUID().toString().replace("-", "") + lastName;
        return uuidFileName;
    }

    public static String nullHandler(String originalFilename) {
        //防止空字符注入：
        StringBuffer sb = new StringBuffer();
        for (int k = 0; k < originalFilename.length(); k++) {
            if ('\u0000' != originalFilename.charAt(k)) {
                sb.append(originalFilename.charAt(k));
            }
        }
        return sb.toString();
    }
}
